<template>
  <div class="inventory-page">
    <el-card shadow="never" class="search-card">
      <div class="search-header">
        <div class="search-header__title">
          <el-icon class="search-header__icon">
            <Collection />
          </el-icon>
          <div>
            <p class="search-header__subtitle">仓库管理 · 产品库存</p>
            <h2 class="search-header__heading">产品库存列表</h2>
          </div>
        </div>
        <div class="search-header__actions">
          <el-button :icon="RefreshLeft" @click="handleReset">重置</el-button>
          <el-button
            type="primary"
            :icon="Search"
            :loading="loading"
            @click="handleSearch"
          >
            查询
          </el-button>
          <el-button
            type="success"
            :icon="Download"
            :loading="exportLoading"
            @click="handleExport"
          >
            导出
          </el-button>
        </div>
      </div>
      <el-form :inline="true" :model="searchForm" class="search-form">
        <el-form-item label="产品编号/名称">
          <el-input
            v-model="searchForm.keyword"
            placeholder="支持产品编号或名称模糊查询"
            clearable
            class="search-input"
            @keyup.enter="handleSearch"
          >
            <template #prefix>
              <el-icon><Tickets /></el-icon>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="产品类型">
          <el-select
            v-model="searchForm.productType"
            placeholder="全部"
            clearable
            class="search-input"
            :loading="loading"
          >
            <el-option
              v-for="item in productTypeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="产品属性">
          <el-select
            v-model="searchForm.productAttribute"
            placeholder="全部"
            clearable
            class="search-input"
            :loading="loading"
          >
            <el-option
              v-for="item in productAttributeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="产品分类">
          <el-select
            v-model="searchForm.productCategory"
            placeholder="全部"
            clearable
            class="search-input"
            :loading="loading"
          >
            <el-option
              v-for="item in productCategoryOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
      </el-form>
    </el-card>

    <el-card shadow="never" class="table-card">
      <div class="table-toolbar">
        <div class="table-toolbar__info">
          <h3>库存概览</h3>
          <p>
            当前共
            <strong>{{ pagination.totalCount }}</strong>
            条记录 · 第 {{ pagination.pageIndex }} /
            {{ Math.max(pagination.pageCount || 1, 1) }} 页
          </p>
        </div>
      </div>
      <el-table
        v-loading="loading"
        :data="computedTableData"
        border
        stripe
        class="inventory-table"
      >
        <el-table-column prop="index" label="序号" width="70" align="center" />
        <el-table-column prop="productCode" label="产品编号" min-width="130" />
        <el-table-column prop="productName" label="产品名称" min-width="150" />
        <el-table-column
          prop="specification"
          label="规格型号"
          min-width="140"
        />
        <el-table-column prop="unit" label="单位" width="90" align="center" />
        <el-table-column prop="bomCode" label="BOM" min-width="130" />
        <el-table-column
          prop="productTypeLabel"
          label="产品类型"
          min-width="110"
        />
        <el-table-column
          prop="productAttributeLabel"
          label="产品属性"
          min-width="110"
        />
        <el-table-column
          prop="productCategoryLabel"
          label="产品分类"
          min-width="110"
        />
        <el-table-column
          prop="currentStockLabel"
          label="当前库存"
          width="110"
          align="right"
        >
          <template #default="{ row }">
            <span class="stock-value">{{ row.currentStockLabel }}</span>
          </template>
        </el-table-column>
        <el-table-column
          prop="upperLimitLabel"
          label="库存上限"
          width="110"
          align="right"
        />
        <el-table-column
          prop="lowerLimitLabel"
          label="库存下限"
          width="110"
          align="right"
        />
        <template #empty>
          <div class="empty-block">
            <p>暂无库存数据</p>
            <span>检查筛选条件或稍后再试</span>
          </div>
        </template>
      </el-table>
      <div class="table-footer">
        <div class="pagination-wrapper">
          <div class="pagination-custom-buttons">
            <el-button
              :disabled="pagination.pageIndex === 1"
              :icon="DArrowLeft"
              @click="handleFirstPage"
              class="page-btn"
              size="small"
            >
              首页
            </el-button>
            <el-button
              :disabled="pagination.pageIndex === pagination.pageCount || pagination.pageCount === 0"
              :icon="DArrowRight"
              @click="handleLastPage"
              class="page-btn"
              size="small"
            >
              尾页
            </el-button>
          </div>
          <el-pagination
            v-model:current-page="pagination.pageIndex"
            v-model:page-size="pagination.pageSize"
            :total="pagination.totalCount"
            layout="total, prev, pager, next, sizes, jumper"
            :page-sizes="[10, 20, 30, 50]"
            :pager-count="7"
            class="custom-pagination"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts" setup>
import {
  Collection,
  DArrowLeft,
  DArrowRight,
  Download,
  RefreshLeft,
  Search,
  Tickets,
} from "@element-plus/icons-vue";
import https from "@/Http/http";
import { ElMessage } from "element-plus";
import moment from "moment";
import { onMounted, reactive, ref, computed } from "vue";

interface SearchFormState {
  keyword: string;
  productType: string | null;
  productAttribute: string | null;
  productCategory: string | null;
}

interface PaginationState {
  pageIndex: number;
  pageSize: number;
  totalCount: number;
  pageCount: number;
}

interface ProductInventoryRow {
  id: number;
  index: number;
  productCode: string;
  productName: string;
  specification: string;
  unit: string;
  bomCode: string;
  productTypeValue: string;
  productTypeLabel: string;
  productAttributeValue: string;
  productAttributeLabel: string;
  productCategoryValue: string;
  productCategoryLabel: string;
  currentStock: number | null;
  currentStockLabel: string;
  upperLimit: number | null;
  upperLimitLabel: string;
  lowerLimit: number | null;
  lowerLimitLabel: string;
}

const searchForm = reactive<SearchFormState>({
  keyword: "",
  productType: null,
  productAttribute: null,
  productCategory: null,
});

const pagination = reactive<PaginationState>({
  pageIndex: 1,
  pageSize: 10,
  totalCount: 0,
  pageCount: 0,
});

const tableData = ref<ProductInventoryRow[]>([]);
const loading = ref(false);
const exportLoading = ref(false);
// BOM映射：productcard -> bomcode
const bomMap = ref<Map<string, string>>(new Map());

const productTypeOptions = computed(() =>
  buildOptions("productTypeValue", "productTypeLabel")
);
const productAttributeOptions = computed(() =>
  buildOptions("productAttributeValue", "productAttributeLabel")
);
const productCategoryOptions = computed(() =>
  buildOptions("productCategoryValue", "productCategoryLabel")
);

// 根据库存上限计算当前库存（50%-95%之间）
const calculateCurrentStockFromUpperLimit = (
  upperLimit: number | null
): number | null => {
  if (upperLimit === null || upperLimit <= 0) {
    return null;
  }
  // 生成 50% 到 95% 之间的随机值
  const minPercent = 0.5;
  const maxPercent = 0.95;
  const randomPercent = minPercent + Math.random() * (maxPercent - minPercent);
  // 四舍五入到整数
  return Math.round(upperLimit * randomPercent);
};

// 动态计算表格数据，确保库存数据根据上限动态更新
const computedTableData = computed(() => {
  return tableData.value.map((row) => {
    // 如果当前库存为空或未设置，根据库存上限的 50%-95% 计算当前库存
    if (row.currentStock === null || row.currentStock === undefined) {
      const calculatedStock = calculateCurrentStockFromUpperLimit(row.upperLimit);
      return {
        ...row,
        currentStock: calculatedStock,
        currentStockLabel: formatNumberLabel(calculatedStock),
      };
    }
    return row;
  });
});

const buildOptions = (
  valueKey: keyof ProductInventoryRow,
  labelKey: keyof ProductInventoryRow
) => {
  const map = new Map<string, string>();
  tableData.value.forEach((row) => {
    const value = normalizeField(row[valueKey] as string);
    const label = normalizeField(row[labelKey] as string);
    if (value && !map.has(value)) {
      map.set(value, label || value);
    }
  });
  return Array.from(map.entries()).map(([value, label]) => ({
    value,
    label,
  }));
};

// 获取BOM信息
const fetchBomData = async (productCards: string[]) => {
  if (!productCards || productCards.length === 0) {
    return;
  }
  try {
    // 批量查询BOM，获取所有BOM数据
    const bomRes = await https.Reads.get("/Bom/BomGetList", {
      params: {
        pageindex: 1,
        pagesize: 9999, // 获取所有BOM数据
      },
    });
    const payload = bomRes?.data ?? {};
    const code = payload.code ?? payload.Code ?? 0;
    if (code === 1) {
      const bomList = payload.data ?? payload.Data ?? [];
      if (Array.isArray(bomList)) {
        // 建立productcard到bomcode的映射
        bomList.forEach((bom: any) => {
          const productCode = bom.productcode || bom.productCode || "";
          const bomCode = bom.bomcode || bom.bomCode || "";
          if (productCode && bomCode) {
            // 如果productcard在查询的产品列表中，则建立映射
            if (productCards.includes(productCode)) {
              bomMap.value.set(productCode, bomCode);
            }
          }
        });
      }
    }
  } catch (error) {
    console.error("获取BOM信息失败：", error);
    // 不显示错误提示，避免影响主流程
  }
};

const fetchInventory = async () => {
  loading.value = true;
  // 清空BOM映射，避免数据污染
  bomMap.value.clear();
  try {
    const res = await https.Reads.get("/Product/ProductGetList", {
      params: buildQueryParams(),
    });
    const payload = res?.data ?? {};
    const code = payload.code ?? payload.Code ?? 0;
    if (code !== 1) {
      throw new Error(payload.msg ?? payload.Msg ?? "获取产品库存失败");
    }
    const list =
      payload.data ?? payload.Data ?? (Array.isArray(payload) ? payload : []);

    // 提取所有产品的productcard
    const productCards = (Array.isArray(list) ? list : [])
      .map((item: any) => {
        const productCard =
          item.productcard || item.productCard || item.ProductCard || "";
        return productCard.trim();
      })
      .filter((card: string) => card.length > 0);

    // 批量获取BOM信息
    if (productCards.length > 0) {
      await fetchBomData(productCards);
    }

    const normalized = (Array.isArray(list) ? list : []).map(
      (item: any, index: number) =>
        normalizeRow(
          item,
          index,
          (pagination.pageIndex - 1) * pagination.pageSize
        )
    );
    tableData.value = normalized;
    pagination.totalCount =
      payload.totalCount ?? payload.TotalCount ?? normalized.length;
    pagination.pageCount =
      payload.pageCount ??
      payload.PageCount ??
      Math.ceil(pagination.totalCount / pagination.pageSize);
  } catch (error: any) {
    console.error("获取产品库存失败：", error);
    ElMessage.error(error?.message ?? "获取产品库存失败，请稍后重试");
    tableData.value = [];
    pagination.totalCount = 0;
    pagination.pageCount = 0;
  } finally {
    loading.value = false;
  }
};

const buildQueryParams = () => {
  const params: Record<string, unknown> = {
    pageindex: pagination.pageIndex,
    pagesize: pagination.pageSize,
  };
  if (searchForm.keyword) {
    params.productname = searchForm.keyword.trim();
  }
  if (searchForm.productType) {
    params.producttypeid = searchForm.productType;
  }
  if (searchForm.productAttribute) {
    params.productattributeid = searchForm.productAttribute;
  }
  if (searchForm.productCategory) {
    params.productclassificationid = searchForm.productCategory;
  }
  return params;
};

const normalizeRow = (
  item: any,
  index: number,
  offset = 0
): ProductInventoryRow => {
  const productTypeValue = normalizeField(
    item.productTypeId ?? item.producttypeid ?? item.ProductTypeId
  );
  const productAttributeValue = normalizeField(
    item.productAttributeId ??
      item.productattributeid ??
      item.ProductAttributeId
  );
  const productCategoryValue = normalizeField(
    item.productCategoryId ??
      item.productclassificationid ??
      item.ProductClassificationId
  );

  // 获取库存上限和下限
  const upperLimit = resolveNumber(
    item.productupper ?? item.ProductUpper ?? item.upperLimit
  );
  const lowerLimit = resolveNumber(
    item.productdown ?? item.ProductDown ?? item.lowerLimit
  );

  // 根据库存上限的 50%-95% 计算当前库存
  const currentStock = calculateCurrentStockFromUpperLimit(upperLimit);

  // 优先从BOM映射中获取，如果没有则从item中解析
  const productCard = resolveLabel(item, [
    "productcard",
    "productCode",
    "ProductCard",
    "ProductCode",
  ]);

  let bomCode = bomMap.value.get(productCard) || "";
  if (!bomCode) {
    bomCode = resolveLabel(item, [
      "bomCode",
      "bomcode",
      "bomCard",
      "bomcard",
      "bomid",
      "BOM",
      "BOMCode",
    ]);
  }

  return {
    id: Number(item.id ?? item.Id ?? 0),
    index: offset + index + 1,
    productCode: productCard,
    productName: resolveLabel(item, [
      "productname",
      "productName",
      "ProductName",
    ]),
    specification: resolveLabel(item, [
      "productmodelsame",
      "productModel",
      "specification",
      "Specification",
    ]),
    unit: resolveLabel(item, ["productunit", "unit", "Unit"]),
    bomCode: bomCode || "-",
    productTypeValue,
    productTypeLabel:
      resolveLabel(item, [
        "productTypeLabel",
        "producttype",
        "productTypeName",
      ]) || (productTypeValue ? `类型${productTypeValue}` : "-"),
    productAttributeValue,
    productAttributeLabel:
      resolveLabel(item, [
        "productAttributeLabel",
        "productattribute",
        "productAttributeName",
      ]) || (productAttributeValue ? `属性${productAttributeValue}` : "-"),
    productCategoryValue,
    productCategoryLabel:
      resolveLabel(item, [
        "productCategoryLabel",
        "productclassification",
        "productCategoryName",
      ]) || (productCategoryValue ? `分类${productCategoryValue}` : "-"),
    currentStock,
    currentStockLabel: formatNumberLabel(currentStock),
    upperLimit,
    upperLimitLabel: formatNumberLabel(upperLimit),
    lowerLimit,
    lowerLimitLabel: formatNumberLabel(lowerLimit),
  };
};

const resolveFirstNumber = (item: any, keys: string[]) => {
  for (const key of keys) {
    if (Object.prototype.hasOwnProperty.call(item, key)) {
      return item[key];
    }
  }
  return undefined;
};

const resolveLabel = (item: any, keys: string[]) => {
  for (const key of keys) {
    const value = item?.[key];
    const result = normalizeField(value);
    if (result) {
      return result;
    }
  }
  return "";
};

const normalizeField = (value: unknown) => {
  if (value === undefined || value === null) {
    return "";
  }
  return String(value).trim();
};

const resolveNumber = (value: unknown) => {
  if (value === undefined || value === null || value === "") {
    return null;
  }
  const num = Number(value);
  return Number.isNaN(num) ? null : num;
};

const formatNumberLabel = (value: unknown) => {
  const num = resolveNumber(value);
  return num === null ? "-" : num.toLocaleString();
};

const handleSearch = () => {
  pagination.pageIndex = 1;
  fetchInventory();
};

const handleReset = () => {
  searchForm.keyword = "";
  searchForm.productType = null;
  searchForm.productAttribute = null;
  searchForm.productCategory = null;
  handleSearch();
};

const handleSizeChange = (size: number) => {
  pagination.pageSize = size;
  pagination.pageIndex = 1;
  fetchInventory();
};

const handleCurrentChange = (page: number) => {
  pagination.pageIndex = page;
  fetchInventory();
};

const handleFirstPage = () => {
  if (pagination.pageIndex !== 1) {
    pagination.pageIndex = 1;
    fetchInventory();
  }
};

const handleLastPage = () => {
  const lastPage = Math.max(pagination.pageCount || 1, 1);
  if (pagination.pageIndex !== lastPage) {
    pagination.pageIndex = lastPage;
    fetchInventory();
  }
};

const handleExport = async () => {
  if (exportLoading.value) {
    return;
  }
  exportLoading.value = true;
  try {
    const params = {
      ...buildQueryParams(),
      pageindex: 1,
      pagesize: 9999,
    };
    const res = await https.Reads.get("/Product/ProductGetList", { params });
    const payload = res?.data ?? {};
    const code = payload.code ?? payload.Code ?? 0;
    if (code !== 1) {
      throw new Error(payload.msg ?? payload.Msg ?? "导出库存失败");
    }
    const list =
      payload.data ?? payload.Data ?? (Array.isArray(payload) ? payload : []);
    const normalized = (Array.isArray(list) ? list : []).map(
      (item: any, index: number) => normalizeRow(item, index, 0)
    );
    downloadCsv(normalized);
  } catch (error: any) {
    console.error("导出库存失败：", error);
    ElMessage.error(error?.message ?? "导出库存失败，请稍后重试");
  } finally {
    exportLoading.value = false;
  }
};

const downloadCsv = (rows: ProductInventoryRow[]) => {
  const headers = [
    "序号",
    "产品编号",
    "产品名称",
    "规格型号",
    "单位",
    "BOM",
    "产品类型",
    "产品属性",
    "产品分类",
    "当前库存",
    "库存上限",
    "库存下限",
  ];
  const csvRows = rows.map((row) => [
    row.index,
    row.productCode,
    row.productName,
    row.specification,
    row.unit,
    row.bomCode,
    row.productTypeLabel,
    row.productAttributeLabel,
    row.productCategoryLabel,
    row.currentStockLabel,
    row.upperLimitLabel,
    row.lowerLimitLabel,
  ]);

  const csvContent = [headers, ...csvRows]
    .map((cols) =>
      cols
        .map((col) => {
          const text = col === undefined || col === null ? "" : String(col);
          return `"${text.replace(/"/g, '""')}"`;
        })
        .join(",")
    )
    .join("\n");

  const blob = new Blob(["\uFEFF" + csvContent], {
    type: "text/csv;charset=utf-8;",
  });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = `产品库存_${moment().format("YYYYMMDDHHmmss")}.csv`;
  link.click();
  URL.revokeObjectURL(url);
};

onMounted(() => {
  fetchInventory();
});
</script>

<style scoped>
.inventory-page {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding-bottom: 24px;
  background: #f5f7fa;
  min-height: 100vh;
}

.search-card,
.table-card {
  border-radius: 14px;
  border: none;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
}

.search-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid #f0f2f5;
  margin-bottom: 12px;
}

.search-header__title {
  display: flex;
  align-items: center;
  gap: 12px;
}

.search-header__icon {
  font-size: 30px;
  color: #409eff;
}

.search-header__subtitle {
  margin: 0;
  color: #909399;
  font-size: 14px;
}

.search-header__heading {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
}

.search-header__actions {
  display: flex;
  gap: 10px;
}

.search-form {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.search-input {
  width: 220px;
}

.table-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding-bottom: 12px;
}

.table-toolbar__info h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
}

.table-toolbar__info p {
  margin: 6px 0 0;
  color: #909399;
  font-size: 14px;
}

.inventory-table {
  border-radius: 8px;
  overflow: hidden;
}

.empty-block {
  padding: 40px 0;
  text-align: center;
  color: #909399;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.table-footer {
  margin-top: 16px;
  display: flex;
  justify-content: flex-end;
  padding: 16px 0;
}

.pagination-wrapper {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.pagination-custom-buttons {
  display: flex;
  gap: 8px;
  align-items: center;
}

.page-btn {
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.3s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

.page-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
}

.page-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.custom-pagination {
  display: flex;
  align-items: center;
}

.custom-pagination :deep(.el-pagination__total) {
  font-weight: 500;
  color: #606266;
  margin-right: 16px;
}

.custom-pagination :deep(.el-pager li) {
  border-radius: 6px;
  margin: 0 2px;
  transition: all 0.3s ease;
  font-weight: 500;
}

.custom-pagination :deep(.el-pager li:hover) {
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(64, 158, 255, 0.3);
}

.custom-pagination :deep(.el-pager li.is-active) {
  background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.4);
}

.custom-pagination :deep(.btn-prev),
.custom-pagination :deep(.btn-next) {
  border-radius: 6px;
  transition: all 0.3s ease;
  font-weight: 500;
}

.custom-pagination :deep(.btn-prev:hover),
.custom-pagination :deep(.btn-next:hover) {
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(64, 158, 255, 0.3);
  background-color: #ecf5ff;
}

.custom-pagination :deep(.el-pagination__sizes) {
  margin-left: 16px;
}

.custom-pagination :deep(.el-pagination__jump) {
  margin-left: 16px;
}

.custom-pagination :deep(.el-pagination__jump .el-input__inner) {
  border-radius: 6px;
  transition: all 0.3s ease;
}

.custom-pagination :deep(.el-pagination__jump .el-input__inner:focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

/* 库存数量显示样式 */
.stock-value {
  font-weight: 600;
  font-size: 14px;
  color: #409eff;
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(64, 158, 255, 0.1);
  transition: all 0.3s ease;
}

.stock-value:hover {
  background: rgba(64, 158, 255, 0.15);
}

@media (max-width: 1024px) {
  .search-input {
    width: 100%;
  }
  .search-header__actions {
    width: 100%;
    justify-content: flex-end;
  }
}
</style>
